#web自动化的页面基类

from selenium.webdriver.support.select import Select
import time
import autoit
from selenium.webdriver.common.action_chains import ActionChains


class PageBase(object):
    def __init__(self,driver,base_url):
        self.driver=driver
        self.base_url=base_url

    #UI操作：打开某url：http://oss.52studyit.net/webzdh/form.html
    def open(self,pathUrl):#给路径url，比如："/webzdh/form.html"
        self.driver.get(f"{self.base_url}{pathUrl}")

    #UI操作：定位元素
    def find_ele(self,loc):#loc=“id”,"userA"
        ele=self.driver.find_element(loc[0],loc[1])
        return ele

    def find_eles(self,loc):
        return self.driver.find_elements(loc[0],loc[1])

    # 适合控件：文本框、密码框、多行文本框
    # 给某元素loc输入某数据data
    def input(self,loc,data):
        ele=self.find_ele(loc)
        ele.send_keys(data)


    #对文本框/密码框/多行文本框进行清空并输入数据
    def clearAndInput(self,loc,data):
        ele=self.find_ele(loc)
        ele.clear()
        ele.send_keys(data)

    # 清空文本框 / 密码框 / 多行文本框
    def clear(self,loc):
        ele=self.find_ele(loc)
        ele.clear()

    #点击元素：元素点击
    def click(self,loc):
        ele=self.find_ele(loc)
        ele.click()

    #获取元素的文本内容
    def getEleText(self,loc,isStrip=False):
        ele = self.find_ele(loc)
        text=ele.text
        if isStrip:
            text=text.strip()
        return text

    #获取元素的某属性
    def getEleAttr(self,loc,attrName,isStrip=False):
        ele = self.find_ele(loc)
        attr=ele.get_attribute(attrName)
        if isStrip:
            attr=attr.strip()
        return attr

    #判断元素是否存在
    def isExists(self,loc):
        try:
            self.find_ele(loc)
            return True
        except Exception:
            return False

    #适合：单选按钮
    #功能：选中某选项
    def radio_selectOption(self,attrName,target_value):
        ele1 = self.driver.find_element_by_css_selector(f"input[type='radio'][name='{attrName}'][value='{target_value}']")
        ele1.click()

    #适合：单选按钮
    #功能：获取用户选中的是哪个选项
    def radio_getUserData(self,attrName):
        eles = self.driver.find_elements_by_css_selector(f"input[type='radio'][name='{attrName}']")
        userValue = ""
        for x in eles:
            if x.is_selected():
                userValue = x.get_attribute("value")
                break
        return userValue

    #适合：单选按钮
    #功能：判断某选项是否选中
    def radio_isSelected(self,attrName,target_value):
        ele1 = self.driver.find_element_by_css_selector(f"input[type='radio'][name='{attrName}'][value='{target_value}']")
        status = ele1.is_selected()
        if status:
            return True
        else:
            return False

    #适合：复选框
    #功能：全选
    def checkbo_AllSelect(self,attrName):
        allOptons = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOptons:
            status = x.is_selected()
            if not status:
                x.click()


    #适合：复选框
    #功能：全不选
    def checkbox_AllNotSelect(self,attrName):
        allOptons = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOptons:
            status = x.is_selected()
            if status:
                x.click()

    #适合：复选框
    #功能：反选
    def checkbox_reverseSelect(self,attrName):
        allOptons = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOptons:
            x.click()

    #适合：复选框
    #功能：选中N个选项。N>=0
    def checkbox_selectN(self,attrName,target_values):
        allOptons = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOptons:
            attrValue = x.get_attribute("value")  # "dalanqiu"
            status = x.is_selected()
            if attrValue in target_values:  # 确保该选项一定是选中
                if not status:
                    x.click()
            else:  # 确保该选项一定是未选中
                if status:
                    x.click()

    #适合：复选框
    #功能：获取用户选中了哪些选项
    def checkbox_getUserData(self,attrName):
        userData = ""
        allOptons = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOptons:
            status = x.is_selected()
            if status:
                attrValue = x.get_attribute("value")
                userData += attrValue + ","

        return userData[:-1]

    #适合：复选框
    #功能：判断某选项是否选中
    def checkbox_isSelected(self,attrName,target_value):
        ele = self.driver.find_element_by_css_selector(f"input[type='checkbox'][name='{attrName}'][value='{target_value}']")
        if ele.is_selected():
            return  True
        else:
            return False

    #适合：下拉列表
    #功能：选中某个选项(根据下标选中)
    def select_selectOne_byIndex(self,attrName,optionIndex):
        haha=Select(self.driver.find_element_by_css_selector(f"select[name='{attrName}']"))
        haha.select_by_index(optionIndex)

    # 适合：下拉列表
    # 功能：选中某个选项(根据value选中)
    def select_selectOne_byValue(self, attrName, optionValue):
        haha = Select(self.driver.find_element_by_css_selector(f"select[name='{attrName}']"))
        haha.select_by_value(optionValue)

    # 适合：下拉列表
    # 功能：选中某个选项(根据文本内容选中)
    def select_selectOne_byText(self, attrName, optionText):
        haha = Select(self.driver.find_element_by_css_selector(f"select[name='{attrName}']"))
        haha.select_by_visible_text(optionText)

    #适合：下拉列表
    #功能：获取用户选中的是哪个选项
    def select_getUserData(self,attrName,isStrip=False):
        haha = Select(self.driver.find_element_by_css_selector(f"select[name='{attrName}']"))
        userData = haha.first_selected_option.text
        if isStrip:
            userData=userData.strip()
        return userData


    #适合：日期控件
    #功能：输入某日期
    def input_riqi(self,loc,target_riqi):
        ele_birthday = self.find_ele(loc)

        if ele_birthday.get_attribute("readonly"):
            self.driver.execute_script("arguments[0].removeAttribute('readonly')", ele_birthday)

        self.driver.execute_script("arguments[0].value=arguments[1]", ele_birthday, target_riqi)

    #适合：文件框控件/文件上传
    #功能：上传N个文件/文件夹。N>=0
    def upload(self,loc,target_filesPath):
        if target_filesPath=="" or target_filesPath is None:
            return

        filePaths = ''
        a = target_filesPath.split(",")  # [XX,XX,XXX]
        for x in a:
            filePaths += '"' + x + '" '
        filePaths = filePaths.replace("/", "\\")

        ele_zaopian = self.find_ele(loc)
        ActionChains(self.driver).click(ele_zaopian).perform()
        time.sleep(2)

        autoit.win_wait("打开", 10)
        autoit.control_send("打开", "Edit1", filePaths)
        autoit.control_click("打开", "Button1")

    # 获取三种JS弹出框的文本内容
    def getTextForJsTanCuKuan(self):
        return self.driver.switch_to.alert.text

    # 点击三种JS弹出框的“确定”按钮
    def acceptForJsTanCuKuan(self):
        self.driver.switch_to.alert.accept()

    # 点击三种JS弹出框的“取消”按钮
    def dismissForJsTanCuKuan(self):
        self.driver.switch_to.alert.dismiss()

    # 为JS的prompt弹出框输入文本
    def inputJsTanCuKuan(self, data):
        self.driver.switch_to.alert.send_keys(data)

    #函数：进入子网页
    def switch_frame(self,frameIdorName):
        self.driver.switch_to.frame(frameIdorName)

    #函数：切换到父网页、上一级网页
    def switch_defaultIframe(self):
        self.driver.switch_to.default_content()

    # 函数功能：鼠标单击某元素loc
    def mouse_click(self, loc,):
        ele = self.find_ele(loc,)
        ActionChains(self.driver).click(ele).perform()

    # 函数功能：鼠标双击某元素loc
    def mouse_dbclick(self, loc):
        ele = self.find_ele(loc)
        ActionChains(self.driver).double_click(ele).perform()

    # 函数功能：鼠标悬停在某元素loc
    def mouse_moveToEle(self, loc):
        ele = self.find_ele(loc)
        ActionChains(self.driver).move_to_element(ele).perform()

    #函数：对当前网页信息截图
    def savePng1(self,imgPath):
        self.driver.get_screenshot_as_file(imgPath)

    def savePng2(self,serverName,key):
        imgName=f"{serverName}_{key}_{time.strftime('%Y%m%d%H%M%S')}.png" #"登录_K001_20251028171203.png"
        self.driver.get_screenshot_as_file(f"./screen/{imgName}")
        return imgName #"登录_K001_20251028171203.png"


    #功能：切换到最新窗口/刚刚打开的窗口
    def switchWindow_toNew(self):
        self.driver.switch_to.window(self.driver.window_handles[-1])

    #功能：根据目标窗口的窗口标题来切换到目标窗口
    def switchWindow_by_title(self,targetTitle):
        allHandler=self.driver.window_handles
        for x in allHandler:
            self.driver.switch_to.window(x)
            curTitle=self.driver.title
            if targetTitle in curTitle:
                break

    # 功能：根据目标窗口的窗口url来切换到目标窗口
    def switchWindow_by_url(self, targetUrl):
        allHandler = self.driver.window_handles
        for x in allHandler:
            self.driver.switch_to.window(x)
            curUrl = self.driver.current_url
            if targetUrl in curUrl:
                break

